///////////////////////////////////////////////////////////////////////////////////////////////////
/// \file formic/fqmc/gradient.h
///
/// \brief   header file for the monte carlo gradient function
///
///////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef FORMIC_FQMC_GRADIENT_HEADER
#define FORMIC_FQMC_GRADIENT_HEADER

#include<formic/random/random.h>

#include<boost/shared_ptr.hpp>

namespace formic {

  class InputBase;
  class Configuration;
  template<class S> class CoeffObj;

  namespace fqmc {

    template<class S> class Sampler;

    template<class S> void gradient(const formic::InputBase & userinp,
                                    const boost::shared_ptr<formic::CoeffObj<S> > & co,
                                    double * const grad,
                                    const double * const energy_ptr = 0);

    template<class S> void gradient(const formic::InputBase & userinp,
                                    boost::shared_ptr<formic::fqmc::Sampler<S> > & sampler,
                                    const boost::shared_ptr<formic::CoeffObj<S> > & co,
                                    double * const grad,
                                    const double * const energy_ptr = 0);

    template<class S> void gradient(const formic::InputBase & userinp,
                                    const int burn_len,
                                    const int samp_len,
                                    const formic::Configuration & init_config,
                                    const formic::LaggedFibonacci<> & rng,
                                    const boost::shared_ptr<formic::CoeffObj<S> > & gf,
                                    const boost::shared_ptr<formic::CoeffObj<S> > & vf,
                                    double * const grad,
                                    const double * const energy_ptr = 0);

  }

}

#endif
